﻿#include "hanlddata.h"
#include <QTextCodec>
#include <QDebug>
#include <QDir>
#include <QStandardPaths>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "../coms/comdata.h"

#include "../logs/printlog.h"



#if DATA_TEST
#include <sys/un.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#endif

#define UEVENT_BUFFER_SIZE 2048



HanldData::HanldData(QObject *parent) : QThread(parent)
  , m_isRun(false)
  , m_timer(NULL)
  , m_settings(NULL)
  , m_addComTimer(NULL)
  , m_removeComTimer(NULL)
{

    ComData::gestance();
    m_vendor_id = 0x1995;
    m_product_id= 0x0806;

    m_docParh = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    m_docParh += "/";
    QDir wdir(m_docParh);
    QDir isDir;

    //设置顶端配置路径
    if (!isDir.exists(m_docParh + "fileconfig/configs/cotest")) {


        wdir.mkpath("fileconfig/configs/cotest/" );
    }
    m_docParhFile = m_docParh +"fileconfig/configs/cotest/cotest.ini";
    m_settings= new QSettings (m_docParhFile, QSettings ::IniFormat);
    m_settings->setIniCodec(QTextCodec::codecForName("UTF-8"));

#if DATA_TEST
    m_handle = NULL;
#endif

    connect(this ,SIGNAL(sigAddCurrentDevice() ) ,this ,SLOT(onSigAddCurrentDevice() ) );
    connect(this ,SIGNAL(sigRemoveCurrentDevice() ) ,this ,SLOT(onSigRemoveCurrentDevice() ) );
    connect(this ,SIGNAL(sigAddCurrentComDevice() ) ,this ,SLOT(onSigAddCurrentComDevice() ) );
    connect(this ,SIGNAL(sigRemoveCurrentComDevice() ) ,this ,SLOT(onSigRemoveCurrentComDevice() ) );

    m_timer = new QTimer(this);

    connect(m_timer ,SIGNAL(timeout() ) ,this ,SLOT(onReadTimeData() ) );
    m_removeTimer= new QTimer(this);

    connect(m_removeTimer ,SIGNAL(timeout() ) ,this ,SLOT(onRemoveimeDevice() ) );

    m_addTimer = new QTimer(this);

    connect(m_addTimer ,SIGNAL(timeout() ) ,this ,SLOT(onAddTimeDevice() ) );

    m_addComTimer= new QTimer(this);

    connect(m_addComTimer ,SIGNAL(timeout() ) ,this ,SLOT(onAddTimeComDevice()  ) );

    m_removeComTimer = new QTimer(this);

    connect(m_removeComTimer ,SIGNAL(timeout() ) ,this ,SLOT(onRemoveimeComDevice() ) );

    initData();
}

HanldData::~HanldData()
{

    m_isRun = false;
    hid_exit();
}

void HanldData::initData()
{

    m_isRun = true;
    ComData::gestance()->onAddSerielComInfor();
    start();
}

HanldData *HanldData::gestance()
{
    static HanldData hanldData;

    return  &hanldData;
}

int HanldData::init_hotplug_sock()
{
    const int buffersize = 1024;
    int ret;
    int s = 0;
#if DATA_TEST
    struct sockaddr_nl snl;
    bzero(&snl, sizeof(struct sockaddr_nl));
    snl.nl_family = AF_NETLINK;
    snl.nl_pid = getpid();
    snl.nl_groups = 1;
    s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
    if (s == -1)
    {
        perror("socket");
        return -1;
    }
    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
    ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
    if (ret < 0)
    {
        perror("bind");
        close(s);
        return -1;
    }

#endif
    return s;
}

bool HanldData::initHandl()
{
    bool status = false;
#if DATA_TEST
    if(m_handle){
        hid_init();
        m_handle = hid_open(m_vendor_id , m_product_id, NULL);

        if(m_handle != NULL){
            status = true;
            QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  +" contents ="+" success";
            PrintLog::gestance()->printInfor(logStr);
        }else{
            QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  +" contents ="+" failed";
            PrintLog::gestance()->printInfor(logStr);
        }
    }else{
        // hid_close(m_handle);
        //   hid_exit();

        //   hid_init();
        m_handle = hid_open(m_vendor_id , m_product_id, NULL);
        if(m_handle != NULL){
            status = true;
            QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  +" contents ="+" erci success";
            PrintLog::gestance()->printInfor(logStr);
        }else{
            QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  +" contents ="+" erci failed";
            PrintLog::gestance()->printInfor(logStr);
        }
    }
#endif
    qDebug()<<"HanldData::initHandl status=="<<status;

    return status;
}
/*
20 30 10 0a 60 88 07 08 09 0a 0b
0c 0d 0e 0f 10 11 12 13 14 01 16
17 18 19 1a 1b 1c 1d 1e 00 00 00
53 23 24 25 26 27 28 29 2a 2b 2c
2d 2e 2f 30 31 32 33 34 35 36 37
38 39 3a 3b 3c 3d 0e 0f ff
*/
int HanldData::readData()
{
    int res = 0;
    unsigned char usb_data[65];
    int nums = 0;
    char types = 0;
    bool isTrue1 = false;
    bool isTrue2 = false;
    bool isTrue3 = false;
    QByteArray infors;
#if DATA_TEST
    if(m_handle){
        memset(usb_data,0x00,65);
        res = hid_read_timeout(this->m_handle, usb_data, 64, 1);
        qDebug()<<"tempInfors tempInfors res=="<<res;

        if(res>0)
        {
            isTrue1 = false;
            isTrue2 = false;
            isTrue3 = false;
            for(int i=0; i<res; i++)
            {
                infors += QByteArray((char *)&usb_data[i],1);

            }
            QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  +" infors ="+infors.toHex();
            PrintLog::gestance()->printInfor(logStr);
            types = usb_data[20];
            if(usb_data[0] == 0x20 && usb_data[1]== 0x30 && usb_data[2]== 0x10){

                isTrue1 = true;


            }
            if(isTrue1 ){
                if(usb_data[3] == 0x0a && usb_data[4]== 0x60 && usb_data[5]== 0x88){
                    isTrue2 = true;

                }
            }
            if(isTrue1 && isTrue2){
                if(usb_data[61] == 0x0E && usb_data[62]== 0x0F){
                    isTrue3 = true;

                }
            }

            if(isTrue1 && isTrue2 && isTrue3 ){
                if(types == 0 || types == 1 || types == 2 || types == 3){
                    int data = 0;
                    char data1 =usb_data[30];
                    data = data1;
                    char data2 =usb_data[31] ;
                    data = (data << 8) +data2;
                    char data3 =usb_data[32];
                    data = (data << 8) +data3;
                    char data4 =usb_data[33];
                    data = (data << 8) +data4;
                    nums = data;

                    emit sigCurrentData( nums);
                }else{
                    if( types == 5){
                        int data = 0;
                        char data1 =usb_data[30];
                        data = data1;
                        char data2 =usb_data[31] ;
                        data = (data << 8) +data2;
                        char data3 =usb_data[32];
                        data = (data << 8) +data3;
                        char data4 =usb_data[33];
                        data = (data << 8) +data4;
                        nums = data;

                        emit sigAddCurrentData( nums);
                    }

                }
            }


        }
    }

    //  QByteArray tempInfors((char *)usb_data,65);
    // qDebug()<<"tempInfors tempInfors=="<<tempInfors.toHex();

#endif

    return res;
}

int HanldData::readCurrentData()
{
    int lens = 0;
    int res = writeData(1,lens);


    if(m_timer != NULL){
        m_timer->start(50);
    }
    return res;
}

int HanldData::readHeartData()
{
    int lens = 0;
    int res = writeData(0,lens);


    if(m_timer != NULL){
        m_timer->start(50);
    }
    return res;
}

int HanldData::readMcuData()
{
    int lens = 0;
    int res = writeData(3,lens);


    if(m_timer != NULL){
        m_timer->start(50);
    }
    return res;
}

int HanldData::readMcuClearData()
{
    int lens = 0;
    int res = writeData(5,lens);


    if(m_timer != NULL){
        m_timer->start(50);
    }
    return res;
}

/*
* 从坐标30开始
* 类型坐标是20
* type = 0 心跳包
* type = 1 读取个数
* type = 2 写入数据
* type = 3 读取个数下位机自动减一
* type =5 取出所有数据 mcu清零
*/

int HanldData::writeData(int type,int lens)
{
    int res = 0;
    unsigned char usb_data[65];
    memset(usb_data,0x00,65);

    char types = (char)type;
    int datas = lens;
    int space= 1;

    for(int i=0; i<65; i++)
    {
        usb_data[i]= (char)i;

    }

    usb_data[0+space]= 0x20;
    usb_data[1+space]= 0x30;
    usb_data[2+space]= 0x10;
    usb_data[3+space]= 0x0a;
    usb_data[4+space]= 0x60;
    usb_data[5+space]= 0x88;

#if DATA_TEST

    usb_data[20+space]= type;
    char data1 =((datas &0xFF000000 ) >> 24);
    usb_data[30+space]= data1;
    char data2 =((datas &0x00FF0000 ) >> 16);
    usb_data[31+space]= data2;
    char data3 =((datas &0x0000FF00 ) >> 8);
    usb_data[32+space]= data3;
    char data4 =((datas &0x000000FF ));
    usb_data[33+space]= data4;
    usb_data[61+space]= 0x0E;
    usb_data[62+space]= 0x0F;
    usb_data[63+space]= 0xFF;

    res = hid_write(this->m_handle, usb_data, 65);
#endif
    return res;
}

void HanldData::setCurrentValue(QString nums)
{
    if(m_settings != NULL){
        m_settings->beginGroup("cotest");
        m_settings->setValue("currentNumber",nums);
        m_settings->endGroup();
    }
}

int HanldData::getCurrentValue()
{
    QString stra = "";
    if(m_settings != NULL){
        m_settings->beginGroup("cotest");
        stra = m_settings->value("currentNumber",QVariant("")).toString();

        m_settings->endGroup();
    }
    if(stra.length() <= 0){
        stra="0";
    }
    return stra.toInt();
}

void HanldData::onReadTimeData()
{
    readData();
}

void HanldData::onAddTimeDevice()
{
    qDebug()<<"HanldData::onAddTimeDevice";
    if(m_addTimer != NULL){
        m_addTimer->stop();
    }
    QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  ;
    PrintLog::gestance()->printInfor(logStr);
    emit sigAddDevice();
}

void HanldData::onRemoveimeDevice()
{

    qDebug()<<"HanldData::onRemoveimeDevice";
    if(m_removeTimer != NULL){
        m_removeTimer->stop();
    }
    //  hid_init();
    struct hid_device_info * P_device;

    P_device = hid_enumerate(0, 0);

    bool isStops =false;
    int vendor_id= 0x1995;

    int product_id= 0x0806;

    while(P_device != NULL)
    {
        if(vendor_id == P_device->vendor_id && product_id ==  P_device->product_id ){
            isStops = true;
        }

        P_device = P_device->next;
    }

    hid_free_enumeration(P_device);
    //  hid_exit();
    if(!isStops){
        QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  +" isStops = true";
        PrintLog::gestance()->printInfor(logStr);
        emit sigRemoveDevice();
    }else{
        QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  +" isStops = false";
        PrintLog::gestance()->printInfor(logStr);
    }

}

void HanldData::onSigAddCurrentDevice()
{
    qDebug()<<"HanldData::onSigAddCurrentDevice";
    if(m_removeTimer != NULL){
        m_removeTimer->stop();
    }
    if(m_addTimer != NULL){
        m_addTimer->stop();
    }

    if(m_addTimer != NULL){
        m_addTimer->start(5000);
    }
}

void HanldData::onSigRemoveCurrentDevice()
{
    qDebug()<<"HanldData::onSigRemoveCurrentDevice";
    if(m_removeTimer != NULL){
        m_removeTimer->stop();
    }
    if(m_addTimer != NULL){
        m_addTimer->stop();
    }
    if(m_removeTimer != NULL){
        m_removeTimer->start(1000);
    }
}

void HanldData::onAddTimeComDevice()
{
    ComData::gestance()->onAddSerielComInfor();
}

void HanldData::onRemoveimeComDevice()
{
    ComData::gestance()->onRemoveSerielComInfor();
}

void HanldData::onSigAddCurrentComDevice()
{
    qDebug()<<"HanldData::onSigAddCurrentComDevice";
    if(m_removeComTimer != NULL){
        m_removeComTimer->stop();
    }
    if(m_addComTimer != NULL){
        m_addComTimer->stop();
    }

    if(m_addComTimer != NULL){
        m_addComTimer->start(2500);
    }
}

void HanldData::onSigRemoveCurrentComDevice()
{
    qDebug()<<"HanldData::onSigRemoveCurrentComDevice";
    if(m_removeComTimer != NULL){
        m_removeComTimer->stop();
    }
    if(m_addComTimer != NULL){
        m_addComTimer->stop();
    }
    if(m_removeComTimer != NULL){
        m_removeComTimer->start(1000);
    }
}

void HanldData::run()
{
    int hotplug_sock = init_hotplug_sock();
    char buf[UEVENT_BUFFER_SIZE * 2] = {0};
    while(m_isRun)
    {
        /* Netlink message buffer */
        memset(buf,0x00,UEVENT_BUFFER_SIZE * 2);
#if DATA_TEST
        recv(hotplug_sock, &buf, sizeof(buf), 0);
#endif
        if(sizeof(buf) > 0){
            QByteArray infor(buf);
            QString temps(infor);
            // printf("%s\n", buf);
            qDebug()<<" HanldData::run" << "infor =="<<infor;
            qDebug()<<" HanldData::run" << "temps =="<<temps;
            QString logStr= typeid(this).name()+QString(" %1").arg( __func__) +" -- "+ QString("%1").arg( __LINE__)  +" temps ="+temps;
            PrintLog::gestance()->printInfor(logStr);
            if(temps.contains("remove")  && !temps.contains("1995:0806") && !temps.contains("ttyUSB")){ //&& temps.contains("1995")&& temps.contains("0806")){
                qDebug()<<" HanldData::run" << "sigRemoveDevice ==";
                emit sigRemoveCurrentDevice();

            }

            if(temps.contains("add")&& temps.contains("1995:0806")&& !temps.contains("ttyUSB") ){//&& temps.contains("1995")&& temps.contains("0806")){
                qDebug()<<" HanldData::run" << "sigAddDevice ==";
                //  emit sigAddDevice();

                emit sigAddCurrentDevice();
            }

            if(temps.contains("remove")  && temps.contains("ttyUSB")){ //&& temps.contains("1995")&& temps.contains("0806")){
                qDebug()<<" HanldData::run" << "sigRemoveCurrentComDevice ==";
                emit sigRemoveCurrentComDevice();

            }
            if(temps.contains("add")&& !temps.contains("1995:0806") && temps.contains("ttyUSB") ){//&& temps.contains("1995")&& temps.contains("0806")){
                qDebug()<<" HanldData::run" << "sigAddCurrentComDevice ==";
                //  emit sigAddDevice();
                emit sigAddCurrentComDevice();

            }
            //msleep(50);
        }else{
            msleep(80);
        }


    }

}
